home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
jovept2.arc
/
MAKE.C
< prev
next >
Wrap
Text File
|
1985-05-30
|
10KB
|
438 lines
/* file make.c */
/* simplified "make" for ms-dos */
/* from usenet posting. */
long dateof(), max(), min(), make();
unsigned char *envfind();
#include <stdio.h>
#include "bdos.h"
#define ERROR -1
#define TRUE 1
#define FALSE 0
#define DEFAULT "MAKEFILE"
#define INMAX 130 /* maximum input line length */
#define DEPENDANT 1 /* used in calling getmodified */
#define DEFINED 2
struct howrec {
char *howcom,*howargs;
struct howrec *nexthow;
};
struct deprec {
char *name;
struct defnrec *def;
struct deprec *nextdep;
};
struct defnrec {
char *name;
int uptodate;
long modified;
struct deprec *dependson;
struct howrec *howto;
struct defnrec *nextdefn;
};
struct dorec {
char *name;
struct dorec *nextdo;
};
struct defnrec *defnlist;
struct dorec *dolist;
int execute;
int stopOnErr;
int madesomething;
int knowhow;
int no_file;
main(argc,argv)
int argc;
char *argv[];
{
no_file = 1;
set_dta();
init(argc,argv);
/* now fall down the dolist and do them all */
while (dolist != NULL) {
madesomething = FALSE;
make(dolist->name);
if (!madesomething) {
if (knowhow) {
fprintf(stderr,"Make: '%s' is up to date.",dolist->name);
} else {
fprintf(stderr,
"Make: Don't know how to make '%s'.",dolist->name);
if (stopOnErr)
exit(-1);
}
}
dolist = dolist->nextdo;
}
}
init(argc,argv)
int argc;
char *argv[];
{
int i, usedefault;
dolist = NULL;
defnlist = NULL;
usedefault = TRUE;
execute = TRUE;
stopOnErr = TRUE;
for (i=1; i < argc; i++) {
if (argv[i][0] == '-') { /* option */
switch (argv[i][1]) {
case 'f': case 'F': /* arg following is a makefile */
if (++i < argc) {
readmakefile(argv[i]);
usedefault = FALSE;
} else {
fprintf(stderr,"Make: '-f' requires filename");
exit(-1);
}
break;
case 'i': case 'I': /* ignore errors on execution */
stopOnErr = FALSE;
break;
case 'n': case 'N': /* don't execute commands - just print */
execute = FALSE;
break;
default:
fprintf(stderr,"Make: unknown option '%s'.",argv[i]);
}
} else { /* it must be something to make */
add_do(argv[i]);
no_file = 0;
}
}
if (usedefault)
readmakefile(DEFAULT);
}
long make(s) /* returns the modified date/time */
char *s;
{
struct defnrec *defnp;
struct deprec *depp;
struct howrec *howp;
long latest, getmodified(), max();
/* look for the definition */
defnp = defnlist;
while (defnp != NULL) {
if (strcmp(defnp->name,s) == 0)
break;
defnp = defnp->nextdefn;
}
if (defnp == NULL) { /* don't know how to make it */
knowhow = FALSE;
latest = getmodified(s,DEFINED);
if (latest==0) { /* doesn't exist but don't know how to make */
fprintf(stderr,"Make: Can't make '%s'.",s);
exit(-1);
} else /* exists - assume it's up to date since we don't know */
return(latest);
}
if (defnp->uptodate)
return(defnp->modified);
/* now make sure everything that it depends on is up to date */
latest = 0;
depp = defnp->dependson;
while (depp != NULL) {
latest = max(make(depp->name),latest);
depp = depp->nextdep;
}
knowhow = TRUE; /* has dependencies therefore we know how */
/* if necessary, execute all of the commands to make it */
/* if (out of date) || (depends on nothing) */
if (latest > defnp->modified || defnp->dependson==NULL) {
/* make those suckers */
howp = defnp->howto;
while (howp != NULL) {
/* printf("%s %s\n",howp->howcom,howp->howargs); */
if (execute) {
char filename[100]; /* extra space */
if (1) {
if (execl(howp->howcom,howp->howargs) != 0) {
fprintf(stderr,
"Make: error from %s",howp->howcom);
if (stopOnErr)
exit(-1);
}
} else {
fprintf(stderr,"Make: Can't find '%s'.",
howp->howcom);
if (stopOnErr)
exit(-1);
}
putchar('\n'); /* in case command leaves us dangling */
}
howp = howp->nexthow;
}
/* Only say it`s as recent as it's latest dependent - that way
if we don't actually have a file for this dependency, it works
ok
*/
defnp->modified = latest;
defnp->uptodate = TRUE;
if (defnp->howto != NULL) /* we had instructions */
madesomething = TRUE;
}
return(defnp->modified);
}
add_do(s)
char *s;
{
struct dorec *ptr1, *ptr2;
char *getmem();
ptr1 = getmem(sizeof(struct dorec));
ptr1->name = s; /* okay since only called with an argv */
ptr1->nextdo = NULL;
uppercase(ptr1->name);
/* now go down the dolist */
if (dolist == NULL)
dolist = ptr1;
else {
ptr2 = dolist;
while (ptr2->nextdo != NULL)
ptr2 = ptr2->nextdo;
ptr2->nextdo = ptr1;
}
}
readmakefile(s)
char *s;
{
FILE *fil;
int doneline, pos, i, j;
char inline[INMAX], info[INMAX];
char *getmem();
struct defnrec *defnp, *defnp2;
struct deprec *depp, *depp2;
struct howrec *howp, *howp2;
if ( (fil = fopen(s,"r")) < 0) {
fprintf(stderr,"Make: Couldn't open '%s'.",s);
return;
}
while (fgets(inline,INMAX,fil) != NULL) {
inline[strlen(inline) - 1] = '\0';
if (inline[0] == '\0') /* ignore blank lines */
continue;
if (!isspace(inline[0])) { /* start of a new definition */
uppercase(inline);
/* get what we're defining into info */
if (sscanf(inline,"%s ",info) != 1) {
fprintf(stderr,"Make: Can't scan: '%s'.",inline);
continue;
}
/* test for wildcards in file being defined */
for(i=0;info[i]!='\0';i++)
if (s[i]=='?' || s[i]=='*') {
fprintf(stderr,"Make: Definition of '%s'.",info);
fprintf(stderr," contains wildcard.");
break;
}
/* get a new struct */
defnp = getmem(sizeof(struct defnrec));
/* add it to the end of defnlist */
if (defnlist == NULL)
defnlist = defnp;
else {
defnp2 = defnlist;
while (defnp2->nextdefn != NULL)
defnp2 = defnp2->nextdefn;
defnp2->nextdefn = defnp;
}
/* initialize it */
defnp->name = getmem(strlen(info)+1);
strcpy(defnp->name,info);
if(no_file) {
add_do(defnp->name);
no_file = 0;
}
defnp->uptodate = FALSE; /* actually unknown */
defnp->modified = getmodified(defnp->name,DEFINED);
defnp->dependson = NULL;
defnp->howto = NULL;
defnp->nextdefn = NULL;
/* now go through all of its dependecies */
/* first move past the first name */
pos = 0;
while (isspace(inline[pos]))
pos++;
while (!isspace(inline[pos]) && inline[pos]!='\0')
pos++;
/* now loop through those suckers */
doneline = FALSE;
while (!doneline) {
while (isspace(inline[pos]))
pos++;
if (inline[pos] == '\0') {
doneline = TRUE;
continue;
}
for(i = 0; !isspace(inline[pos]) && inline[pos]!='\0'; )
info[i++] = inline[pos++];
info[i] = '\0';
/* get a new struct */
depp = getmem(sizeof(struct deprec));
/* add it to the end of deplist */
if (defnp->dependson == NULL)
defnp->dependson = depp;
else {
depp2 = defnp->dependson;
while (depp2->nextdep != NULL)
depp2 = depp2->nextdep;
depp2->nextdep = depp;
}
depp->name = getmem(strlen(info)+1);
strcpy(depp->name,info);
depp->nextdep = NULL;
}
} else { /* a how to line that starts with blank or tab */
if (defnp == NULL) {
fprintf(stderr,"Make: Howto line without a definition.");
fprintf(stderr,"Make: '%s'.",inline);
}
/* now split the line up into command and args */
for (pos=0;isspace(inline[pos]); pos++);
;
for (i=pos; !isspace(inline[i]) && inline[i]!='\0'; i++)
;
/* if there is something there, allocate mem and copy */
if (i != pos) {
/* get a new struct */
howp = getmem(sizeof(struct howrec));
/* add it to the end of howlist */
if (defnp->howto == NULL)
defnp->howto = howp;
else {
howp2 = defnp->howto;
while (howp2->nexthow != NULL)
howp2 = howp2->nexthow;
howp2->nexthow = howp;
}
/* copy command filename */
howp->howcom = getmem(i-pos+1);
for(j=0; pos < i; )
howp->howcom[j++] = inline[pos++];
howp->howcom[j] = '\0';
/* now look for any argumentative part */
while (isspace(inline[pos]))
pos++;
howp->howargs = getmem(strlen(inline)-pos + 1);
for(i=0; inline[pos] != '\0'; )
howp->howargs[i++] = inline[pos++];
howp->howargs[i] = '\0';
howp->nexthow = NULL;
}
}
}
}
uppercase(s)
char *s;
{
for( ; *s != '\0'; s++)
*s = toupper(*s);
}
char *getmem(size)
int size;
{
char *p;
if ((p = malloc(size)) == 0) {
fprintf(stderr,"Make: Ran out of memory.");
exit(-1);
}
return(p);
}
long getmodified(name,which)
char *name;
int which;
{
static int save_es, dta_seg, dta_offset;
long datetime, dateof(), max(), min();
datetime = 0; /* as old as possible if does not exist */
set_dta();
if (find_first(name) == 0) { /* at least one matching file exists */
datetime = dateof();
/* now loop through all the rest of the matching files */
while (find_next() == 0) {
if (which == DEPENDANT)
datetime = max(datetime, dateof());
else /* this is DEFINED */
datetime = min(datetime, dateof());
}
} else /* doesn't exist */
datetime = 0; /* as old as possible */
return(datetime);
}
long max(a,b)
long a,b;
{
return(a>b ? a : b);
}
long min(a,b)
long a,b;
{
return(a>b ? b : a);
}